package com.itheima.health.service.impl;

import com.itheima.health.dao.CountingDao;
import com.itheima.health.dto.*;
import com.itheima.health.pojo.Order;
import com.itheima.health.service.CountingService;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

@Service
public class CountingServiceImpl implements CountingService {
    @Autowired
    private CountingDao countingDao;
    /*
    * 获取会员数量
    * */
    @Override
    public MemberReportParam getMemberReport() {
        //先创建一个对象 来村查询的数据
        MemberReportParam memberReportParam = new MemberReportParam();
        //创建两个集合来村日期和数量
        List<String> setinglist = new ArrayList<>();
        List<Integer> integerlist = new ArrayList<>();
        //获取今天日期
        LocalDate todayDate = LocalDate.now();
        //获取前三个月的日期
        for (int i = 3; i >=0 ; i--) {
            //获取该月前三个日期
            LocalDate first = LocalDate.of(todayDate.getYear(), todayDate.getMonth().minus(i), 1);
            //获取该月的最后一天
            LocalDate lasDate = first.withDayOfMonth(first.getMonth().length(first.isLeapYear()));
            //根据日期查询当月前的会员数量
            setinglist.add(todayDate.getYear()+"-"+todayDate.getMonth().minus(i).getValue());
           Integer count =  countingDao.getMemberReport(first,lasDate);
           integerlist.add(count);
        }
        memberReportParam.setMonths(setinglist);
        memberReportParam.setMemberCount(integerlist);
        return memberReportParam;
    }
    /*
     * 套餐占比
     * */
    @Override
    public SetmealReportParam getSetmealReport() {
        SetmealReportParam setmealReportParam = new SetmealReportParam();
        //查询当天的套餐占比
        //获取当前时间
        LocalDate todayDate = LocalDate.now().minusDays(3);
        //查询今日套餐预约的名称
        List<SetmealAnalyDto> setSsetmeal = countingDao.gettodayDateSetmeal(todayDate);

        //查询今日预约总套餐
        Integer count =  countingDao.getSetmealNuber(todayDate);

        //根据套餐名称 查询套餐数量
        List<Map> maps = new ArrayList<>();
        for (SetmealAnalyDto setmealAnalyDto : setSsetmeal) {
            Map map= new HashMap();
            map.put("name",setmealAnalyDto.getName());
            map.put("value",setmealAnalyDto.getSetmeal_count() * 1.0 / count);
            maps.add(map);
        }
        setmealReportParam.setSetmealCount(maps);
        return setmealReportParam;
    }
/*
* 获取运营数据
* */
    @Override
    public BusinessData getbusinessRepor() {
        //获取当天日期
        LocalDate todayDate = LocalDate.now();
        //获取一星期的第一天和最后一天
        DatastatisticsDateObject getdateObject = null;
        try {
            getdateObject = getdate(todayDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        LocalDate thisStaWeekdate = getdateObject.getThisStaWeekdate();
        LocalDate thisEndweekdate = getdateObject.getThisEndweekdate();
        //获取该月的第一天个最后一天
        LocalDate beng = LocalDate.of(todayDate.getYear(), todayDate.getMonth(), 1);
        LocalDate end = beng.withDayOfMonth(beng.getMonth().length(beng.isLeapYear()));
        //创建一个集合存储套餐占比详情
        List<SetmealAnalyDto> list = new ArrayList<>();
        //查询今日热门套餐
        List<SetmealAnalyDto> setmeal = countingDao.gettodayDateSetmeal(todayDate);
        //如果今日没有套餐 就不参加比较
        if(setmeal.size() != 0){
            //查询今日套餐总预约数
            Integer numb = countingDao.getSetmealNuber(todayDate);
            //把预约数转换成小数
            DecimalFormat df = new DecimalFormat("0.00");
            for (SetmealAnalyDto setmealAnalyDto : setmeal) {
                if (setmeal.size() == 1){
                    //如果今日只有一个预约
                    setmealAnalyDto.setProportion(1.0);
                }else {
                    setmealAnalyDto.setProportion(Double.valueOf(setmealAnalyDto.getSetmeal_count() * 1.0 /numb));
                }
                list.add(setmealAnalyDto);
            }
        }
        BusinessData businessData = new BusinessData();
        businessData.setHotSetmeal(list);//套餐占比
        businessData.setReportDate(todayDate); //今日日期
        businessData.setTodayNewMember(countingDao.gettodayeNewmber(todayDate));//新增会员
        businessData.setTotalMember(countingDao.gettodayeNewmber(null));//总会员数
        businessData.setThisWeekNewMember(countingDao.getWookNermber(thisStaWeekdate,thisEndweekdate));//本周新增会员
        businessData.setThisMonthNewMember(countingDao.getmonthNewnumb(beng,end));//本月新增会员
        businessData.setTodayOrderNumber(countingDao.getOrderNumb(todayDate));//今日预约
        businessData.setTodayVisitsNumber(countingDao.getVisitNumb(todayDate, Order.ORDERSTATUS_YES));//今日到珍
        businessData.setThisWeekOrderNumber(countingDao.getOrderWeeknumb(thisStaWeekdate,thisEndweekdate));//本周预约数
        businessData.setThisWeekVisitsNumber(countingDao.getVisitOrderNumb(thisStaWeekdate,thisEndweekdate,Order.ORDERSTATUS_YES));//本周到诊
        businessData.setThisMonthOrderNumber(countingDao.getMontOrder(beng,end));//本月预约数
        businessData.setThisMonthVisitsNumber(countingDao.getMontOrderVisit(beng,end,Order.ORDERSTATUS_YES));//本月到诊
        return businessData;
    }
/*
* 导出expox表
* */
    @Override
    public void export(HttpServletResponse response) {
        //查询数据库 准备数据
        //获取当天日期
        LocalDate todayDate = LocalDate.now();
        //获取一星期的第一天和最后一天
        DatastatisticsDateObject getdateObject = null;
        try {
            getdateObject = getdate(todayDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
        LocalDate thisStaWeekdate = getdateObject.getThisStaWeekdate();
        LocalDate thisEndweekdate = getdateObject.getThisEndweekdate();
        //获取该月的第一天个最后一天
        LocalDate beng = LocalDate.of(todayDate.getYear(), todayDate.getMonth(), 1);
        LocalDate end = beng.withDayOfMonth(beng.getMonth().length(beng.isLeapYear()));
        //获取本文件写入数据
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/report_template.xlsx");
        //创建一个文件表格
        try {
            XSSFWorkbook excel = new XSSFWorkbook(in);
            //获取第一个工作波
            XSSFSheet sheet = excel.getSheetAt(0);//通过索引获得
            //获取第三行
            XSSFRow row = sheet.getRow(2);
            //获取第六个单元格
            XSSFCell cell = row.getCell(5);
            //写入数据
            cell.setCellValue(todayDate.toString());
            //填充其他shuj
            row = sheet.getRow(4);
            cell= row.getCell(5);
            cell.setCellValue(countingDao.gettodayeNewmber(todayDate));//新增会员数

            row=sheet.getRow(4);
            cell=row.getCell(7);
            cell.setCellValue(countingDao.gettodayeNewmber(null));//总会员数

            row=sheet.getRow(5);
            cell = row.getCell(5);
            cell.setCellValue(countingDao.getWookNermber(thisStaWeekdate,thisEndweekdate));//本周新增会员

            row=sheet.getRow(5);
            cell=row.getCell(7);
            cell.setCellValue(countingDao.getmonthNewnumb(beng,end)); //本月新增会员

            row = sheet.getRow(7);
            cell=row.getCell(5);
            cell.setCellValue(countingDao.getOrderNumb(todayDate)); //今日预约数

            row=sheet.getRow(7);
           cell= row.getCell(7);
            cell.setCellValue(countingDao.getVisitNumb(todayDate, Order.ORDERSTATUS_YES)); //今日到诊数

            row =sheet.getRow(8);
            cell=row.getCell(5);
            cell.setCellValue(countingDao.getOrderWeeknumb(thisStaWeekdate,thisEndweekdate));//本周预约数

            row=sheet.getRow(8);
            cell=row.getCell(7);
            cell.setCellValue(countingDao.getVisitOrderNumb(thisStaWeekdate,thisEndweekdate,Order.ORDERSTATUS_YES));//本周到诊数

            row=sheet.getRow(9);
            cell= row.getCell(5);
            cell.setCellValue(countingDao.getMontOrder(beng,end));//本月预约数

            row=sheet.getRow(9);
            cell=row.getCell(7);
            cell.setCellValue(countingDao.getMontOrderVisit(beng,end,Order.ORDERSTATUS_YES));//本月到诊数
            //添加热门套餐
            //查询今日热门套餐
            List<SetmealAnalyDto> setmeal = countingDao.gettodayDateSetmeal(todayDate);
            if(setmeal.size() !=0){
                //查询今日套餐总预约数
                Integer numb = countingDao.getSetmealNuber(todayDate);
                //把预约数转换称小数
                DecimalFormat df = new DecimalFormat("0.00");
                int i = 12; //冲12行开始写数据
                for (SetmealAnalyDto setmealAnalyDto : setmeal) {
                   row = sheet.getRow(i);
                    if (row ==null){
                        break;
                    }
                    cell=row.getCell(4);
                    cell.setCellValue(setmealAnalyDto.getName());//套餐名称
                    cell=row.getCell(5);
                    cell.setCellValue(setmealAnalyDto.getSetmeal_count()); //套餐数量
                    cell=row.getCell(6);
                    cell.setCellValue(Double.valueOf(setmealAnalyDto.getSetmeal_count() * 1.0 /numb)); //套餐占比
                    i++;
                }
            }
            //生成一个随机数来给文件命名
            Integer fileName = (int)(Math.random() * 9999) + 100;
            //如果不加这一句浏览器我把我们的excel文件解析称压缩包
            response.setHeader("Content-disposition", "attachment;filename=" + "exportBusinessReport" + fileName + ".xlsx"); //指定导出文件名

            //通过输出流到浏览器下载
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            out.flush();//刷新资源
            //关闭流
            out.close();
            excel.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法
     * 根据当前日期获得当前周的日期
     * @param todayDate
     * @return
     * @throws
     */
    public static DatastatisticsDateObject getdate(LocalDate todayDate) throws Exception {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        cal.setTime(sdf.parse(todayDate.toString()));
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 获取该周第一天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        String beginDate = sdf.format(cal.getTime());
        // 获取该周最后一天
        cal.add(Calendar.DATE, 6);
        String endDate = sdf.format(cal.getTime());

        return  DatastatisticsDateObject.builder()
                .thisStaWeekdate(LocalDate.parse(beginDate))
                .thisEndweekdate(LocalDate.parse(endDate))
                .build();
    }

}
